package sysmessage

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strconv"
	"sync"
)

/**

在 Golang 中高效下载大文件可以使用以下方法：

使用标准库的 net/http 包进行文件下载。你可以使用 http.Get 方法发送 HTTP GET 请求，将服务器上的文件内容下载到本地。这种方法适用于简单的文件下载任务，但不适合处理大文件或需要更高级控制的场景。

使用并发下载和断点续传。对于大文件的下载任务，你可以使用 Goroutines 来实现并发下载，以加快下载速度。同时，你还可以实现断点续传功能，当下载中断后可以从中断处恢复下载，避免重新下载整个文件。

下面是一个简单的示例代码，演示如何在 Golang 中使用并发下载和断点续传来高效下载大文件：


在上面的示例中，通过创建多个 Goroutines 实现了并发下载，并设置了每个 Goroutine 负责下载文件的一部分（使用 HTTP Range 头指定下载范围）。通过这种方式，可以加快大文件的下载速度。

需要注意的是，上面的代码只是一个简单的示例，实际情况中可能需要处理更多的错误和边界情况。同时，对于断点续传功能，你还需要保存已下载部分的信息，以便在恢复下载时使用。
*/

func downloadFile(url, filePath string, start, end int64, wg *sync.WaitGroup) error {
	defer wg.Done()

	client := &http.Client{}
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return err
	}

	if end != 0 {
		req.Header.Set("Range", "bytes="+strconv.FormatInt(start, 10)+"-"+strconv.FormatInt(end, 10))
	}

	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	file, err := os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		return err
	}
	defer file.Close()

	if _, err = file.Seek(start, 0); err != nil {
		return err
	}

	_, err = io.Copy(file, resp.Body)
	if err != nil {
		return err
	}

	return nil
}

func setup_down() {
	url := "http://example.com/largefile.zip"
	filePath := "largefile.zip"
	fileSize := int64(1024 * 1024 * 1024) // 文件大小，假设为 1GB
	concurrency := 5                      // 并发下载的 Goroutines 数量

	var wg sync.WaitGroup
	wg.Add(concurrency)

	chunkSize := fileSize / int64(concurrency)
	for i := 0; i < concurrency; i++ {
		start := int64(i) * chunkSize
		end := start + chunkSize - 1
		if i == concurrency-1 {
			end = fileSize - 1
		}
		go downloadFile(url, filePath, start, end, &wg)
	}

	wg.Wait()
	fmt.Println("Download completed")
}
